-- @preview-file on clear

-- EnemyMovementSystem.lua
-- 敌人专用的移动系统，与玩家分离

local Vector2 = require("vector")

local EnemyMovementSystem = {}
EnemyMovementSystem.__index = EnemyMovementSystem

function EnemyMovementSystem.new(bounds)
    local system = {
        entities = {},
        bounds = bounds or {
            left = 0,
            right = 2560,
            top = 1600,
            bottom = 0,
            width = 2560,
            height = 1600
        },
        gravity = Vector2.new(0, -3100),
        groundPlatforms = {},
        debugMode = false
    }
    
    setmetatable(system, EnemyMovementSystem)
    
    print("敌人移动系统初始化完成")
    return system
end

-- 注册敌人实体
function EnemyMovementSystem:registerEntity(entityData)
    if not entityData.id then
        error("敌人实体必须包含id字段")
    end
    
    local entity = {
        id = entityData.id,
        position = Vector2.new(entityData.position.x, entityData.position.y),
        velocity = Vector2.new(entityData.velocity.x, entityData.velocity.y),
        maxSpeed = entityData.maxSpeed or 200,
        mass = entityData.mass or 1,
        radius = entityData.radius or 20,
        isGrounded = false,
        node = entityData.node,
        lastDirection = entityData.facingDirection or 1,
        moveInput = entityData.moveInput or 0,
        currentSpeed = 0,
        wasGrounded = false,
        isAlive = true,
        moveSpeed = entityData.moveSpeed or 150,  -- 敌人移动速度
        acceleration = 3000,  -- 敌人加速度
        deceleration = 1000,  -- 敌人减速度
        jumpForce = 0,  -- 敌人通常不跳跃，除非特殊AI需要
        _normalizedVelocity = Vector2.new(0, 0),
        _lastHorizontalSpeed = 0,
        _lastInputDirection = 0
    }
    
    self.entities[entityData.id] = entity
    
    if self.debugMode then
        print(string.format("敌人实体注册: %s, 位置: (%.1f, %.1f)", 
            entityData.id, entity.position.x, entity.position.y))
    end
    
    return entity
end

-- 注销敌人实体
function EnemyMovementSystem:unregisterEntity(entityId)
    if self.entities[entityId] then
        self.entities[entityId] = nil
        if self.debugMode then
            print("敌人实体注销: " .. entityId)
        end
        return true
    end
    return false
end

-- 设置地面平台
function EnemyMovementSystem:setGroundPlatforms(platforms)
    self.groundPlatforms = platforms or {}
end

-- 添加地面平台
function EnemyMovementSystem:addGroundPlatform(platform)
    table.insert(self.groundPlatforms, platform)
end

-- 清除所有地面平台
function EnemyMovementSystem:clearGroundPlatforms()
    self.groundPlatforms = {}
end

-- 更新所有敌人实体
function EnemyMovementSystem:update(dt)
    for id, entity in pairs(self.entities) do
        if entity.isAlive then
            -- 保存上一帧的地面状态
            entity.wasGrounded = entity.isGrounded
            
            -- 1. 应用物理力（重力）
            self:_applyPhysics(entity, dt)
            
            -- 2. 处理移动输入
            self:_handleMovement(entity, dt)
            
            -- 3. 临时更新位置
            local newX = entity.position.x + entity.velocity.x * dt
            local newY = entity.position.y + entity.velocity.y * dt
            
            -- 4. 更新位置
            entity.position.x = newX
            entity.position.y = newY
            
            -- 5. 边界检查
            self:_handleBoundaries(entity)
            
            -- 6. 地面碰撞检测
            self:checkGroundCollision(entity)
            
            -- 7. 更新节点位置
            if entity.node then
                entity.node.x = entity.position.x
                entity.node.y = entity.position.y
            end
            
            -- 8. 更新当前速度
            entity.currentSpeed = math.abs(entity.velocity.x)
            
            -- 9. 更新面向方向
            if entity.velocity.x > 0.1 then
                entity.lastDirection = 1
            elseif entity.velocity.x < -0.1 then
                entity.lastDirection = -1
            end
        end
    end
end

-- 应用物理力
function EnemyMovementSystem:_applyPhysics(entity, dt)
    -- 应用重力（只在空中应用）
    if not entity.isGrounded then
        entity.velocity.y = entity.velocity.y + self.gravity.y * dt
    else
        -- 在地面上时，重置垂直速度
        if entity.velocity.y < 0 then
            entity.velocity.y = 0
        end
    end
    
    -- 限制最大下落速度
    local maxFallSpeed = 1200
    if entity.velocity.y < -maxFallSpeed then
        entity.velocity.y = -maxFallSpeed
    end
end

-- 处理移动输入
function EnemyMovementSystem:_handleMovement(entity, dt)
    local targetSpeed = entity.moveInput * entity.moveSpeed
    local currentSpeed = entity.velocity.x
    local speedDifference = targetSpeed - currentSpeed
    
    if math.abs(speedDifference) > 0.1 then
        if math.abs(entity.moveInput) > 0.1 then
            -- 加速
            local acceleration = math.sign(speedDifference) * 
                                math.min(math.abs(speedDifference), entity.acceleration * dt)
            entity.velocity.x = entity.velocity.x + acceleration
        else
            -- 减速
            if entity.isGrounded then
                local deceleration = math.sign(currentSpeed) * 
                                   math.min(math.abs(currentSpeed), entity.deceleration * dt)
                entity.velocity.x = entity.velocity.x - deceleration
                
                if math.abs(entity.velocity.x) < 5 then
                    entity.velocity.x = 0
                end
            end
        end
    end
    
    -- 限制最大速度
    if math.abs(entity.velocity.x) > entity.maxSpeed then
        entity.velocity.x = entity.velocity.x / math.abs(entity.velocity.x) * entity.maxSpeed
    end
end

-- 处理边界
function EnemyMovementSystem:_handleBoundaries(entity)
    local bounds = self.bounds
    
    -- X轴边界检查
    if entity.position.x - entity.radius < bounds.left then
        entity.position.x = bounds.left + entity.radius
        entity.velocity.x = math.max(0, entity.velocity.x)
    elseif entity.position.x + entity.radius > bounds.right then
        entity.position.x = bounds.right - entity.radius
        entity.velocity.x = math.min(0, entity.velocity.x)
    end
    
    -- Y轴边界检查（顶部）
    if entity.position.y + entity.radius > bounds.top then
        entity.position.y = bounds.top - entity.radius
        entity.velocity.y = math.min(entity.velocity.y, 0)
    end
    
    -- Y轴底部边界检查
    if entity.position.y - entity.radius < bounds.bottom - 1000 then
        entity.position.y = bounds.bottom - 1000 + entity.radius
        entity.velocity.y = 0
    end
end

-- 地面碰撞检测
function EnemyMovementSystem:checkGroundCollision(entity)
    entity.isGrounded = false
    
    if #self.groundPlatforms == 0 then
        -- 如果没有地面平台，使用边界地面作为备用
        local bounds = self.bounds
        local entityBottom = entity.position.y - entity.radius
        
        if entityBottom <= bounds.bottom + 5 and entity.velocity.y <= 0 then
            entity.position.y = bounds.bottom + entity.radius
            entity.velocity.y = 0
            entity.isGrounded = true
        end
        return
    end
    
    -- 寻找合适的平台
    local bestPlatform = nil
    local minVerticalDistance = math.huge
    
    for _, platform in ipairs(self.groundPlatforms) do
        local platformTop = platform.y + platform.height
        local entityBottom = entity.position.y - entity.radius
        
        -- 检查水平对齐
        local leftBoundary = platform.x - entity.radius
        local rightBoundary = platform.x + platform.width + entity.radius
        local isHorizontallyAligned = entity.position.x >= leftBoundary and 
                                     entity.position.x <= rightBoundary
        
        if isHorizontallyAligned then
            -- 计算垂直距离：正值表示敌人在平台上方
            local verticalDistance = entityBottom - platformTop
            
            -- 敌人必须在平台上方且在下落或静止
            local isWithinRange = verticalDistance >= 0 and verticalDistance <= 50
            local isFallingOrStable = entity.velocity.y <= 0
            
            if isWithinRange and isFallingOrStable then
                -- 找到最近的平台
                if verticalDistance < minVerticalDistance then
                    minVerticalDistance = verticalDistance
                    bestPlatform = platform
                end
            end
        end
    end
    
    if bestPlatform then
        -- 站在平台上
        local platformTop = bestPlatform.y + bestPlatform.height
        local targetY = platformTop + entity.radius
        
        -- 如果敌人离平台很近，平滑移动到平台顶部
        if math.abs(entity.position.y - targetY) > 1 then
            entity.position.y = targetY
        end
        
        entity.velocity.y = 0
        entity.isGrounded = true
    end
end

-- 设置敌人移动输入
function EnemyMovementSystem:setMoveInput(entityId, input)
    local entity = self.entities[entityId]
    if entity then
        entity.moveInput = input
        return true
    end
    return false
end

-- 设置敌人速度
function EnemyMovementSystem:setVelocity(entityId, velocityX, velocityY)
    local entity = self.entities[entityId]
    if entity then
        entity.velocity.x = velocityX
        entity.velocity.y = velocityY
        return true
    end
    return false
end

-- 应用冲量
function EnemyMovementSystem:applyImpulse(entityId, impulseX, impulseY)
    local entity = self.entities[entityId]
    if entity then
        entity.velocity.x = entity.velocity.x + impulseX / entity.mass
        entity.velocity.y = entity.velocity.y + impulseY / entity.mass
        return true
    end
    return false
end

-- 获取敌人位置
function EnemyMovementSystem:getPosition(entityId)
    local entity = self.entities[entityId]
    return entity and {x = entity.position.x, y = entity.position.y} or nil
end

-- 设置敌人位置
function EnemyMovementSystem:setPosition(entityId, x, y)
    local entity = self.entities[entityId]
    if entity then
        entity.position.x = x
        entity.position.y = y
        
        if entity.node then
            entity.node.x = x
            entity.node.y = y
        end
        return true
    end
    return false
end

-- 获取敌人速度
function EnemyMovementSystem:getVelocity(entityId)
    local entity = self.entities[entityId]
    return entity and {x = entity.velocity.x, y = entity.velocity.y} or nil
end

-- 获取敌人实体
function EnemyMovementSystem:getEntity(entityId)
    return self.entities[entityId]
end

-- 检查敌人是否存活
function EnemyMovementSystem:isAlive(entityId)
    local entity = self.entities[entityId]
    return entity and entity.isAlive or false
end

-- 设置敌人存活状态
function EnemyMovementSystem:setAlive(entityId, isAlive)
    local entity = self.entities[entityId]
    if entity then
        entity.isAlive = isAlive
        return true
    end
    return false
end

-- 重置移动系统
function EnemyMovementSystem:reset()
    self.entities = {}
    self.groundPlatforms = {}
    print("敌人移动系统已重置")
end

-- 获取所有敌人ID
function EnemyMovementSystem:getAllEntityIds()
    local ids = {}
    for id, _ in pairs(self.entities) do
        table.insert(ids, id)
    end
    return ids
end

-- 获取敌人数量
function EnemyMovementSystem:getEntityCount()
    local count = 0
    for _, entity in pairs(self.entities) do
        if entity.isAlive then
            count = count + 1
        end
    end
    return count
end

-- 数学符号函数
function math.sign(x)
    if x > 0 then return 1
    elseif x < 0 then return -1
    else return 0 end
end

return EnemyMovementSystem